/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "引擎数据类型.h"
#include "引擎枚举数据.h"
#include "几何模型生成.h"

#include "Surface.h"
#include "Mesh.h"
#include <三角形.h>



EngineAPI_EXPORT void       f_surface_初始化网格GPU内存(S_设备环境& ctx);
EngineAPI_EXPORT void       f_surface3d_释放GPU内存();

void f_surface2D_管线创建(S_设备环境& ctx);
void f_surface2D_管线销毁(S_设备环境& ctx);

void f_surface3D_管线创建(S_设备环境& ctx);
void f_surface3D_管线销毁(S_设备环境& ctx);



EngineAPI_EXPORT S_Mesh*	f_surface_创建网格对象(S_Mesh* fromesh, S_设备环境& ctx, bool 开启光追, E_网格数据枚举 type = E_网格数据枚举::e_Mesh_CPU);
EngineAPI_EXPORT S_Mesh*	f_surface_创建网格对象(E_网格数据枚举 type = E_网格数据枚举::e_Mesh_CPU);
EngineAPI_EXPORT S_Mesh*	f_surface_创建网格对象(S_设备环境& ctx, E_网格数据枚举 type = E_网格数据枚举::e_Mesh_CPU);
EngineAPI_EXPORT void		f_surface_销毁网格(S_Mesh* mesh);

EngineAPI_EXPORT S_Mesh*	f_surface_创建实例(S_Mesh* 源, bool 关联颜色 = true);
EngineAPI_EXPORT S_Mesh*	f_surface_创建实例(S_Mesh* 源, bool 关联顶点, bool 关联索引, bool 关联UV, bool 关联颜色, bool 关联权重, bool 关联属性);
EngineAPI_EXPORT void		f_surface_关联实例(S_Mesh* mesh, const S_Mesh* 源);
EngineAPI_EXPORT void		f_surface_Copy(S_Mesh* mesh, const S_Mesh* 源);

EngineAPI_EXPORT S_2D画布*	f_surface_创建2D画布(const S_2D画布* fromesh, S_设备环境& ctx);
EngineAPI_EXPORT void		f_surface_释放2D画布(S_2D画布* fromesh);



EngineAPI_EXPORT uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_VNT1>& data);
EngineAPI_EXPORT uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_VN>& data);
EngineAPI_EXPORT uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_VC>& data);
EngineAPI_EXPORT uint32 f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_Aabb>& data);
EngineAPI_EXPORT void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<vec3>& 点, const std::vector<vec3>& 法线, const std::vector<vec2>& UV);
EngineAPI_EXPORT void f_mesh_fill顶点数据(S_Mesh* mesh, const S_GPU内存块& 点, const S_GPU内存块& 法线, const S_GPU内存块& UV);
EngineAPI_EXPORT void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<vec3>& data, uint32 vertFlags);

EngineAPI_EXPORT void f_mesh_fill颜色数据(S_Mesh* mesh, const std::vector<S_RGBA8UI>& col);
EngineAPI_EXPORT void f_mesh_fill顶点颜色(S_Mesh* mesh, const S_RGBA8UI& data);
EngineAPI_EXPORT void f_mesh_fill顶点颜色(S_Mesh* mesh, const std::vector<S_RGBA8UI>& data, uint32 offset);
EngineAPI_EXPORT void f_mesh_fill顶点颜色(S_Mesh* mesh, const S_RGBA8UI& data, uint32 offset, uint32 num);

void f_me_fill顶点(S_Mesh* me, const std::vector<S_VNTC>& vert);
//uint32 f_me_fill顶点(S_Mesh* me, const C_vectorGPU<S_VNTC>& vert);
//EngineAPI_EXPORT uint32 f_me_fill索引(S_Mesh* me, const std::vector<uint32>& index);






template<typename T>
void f_填充顶点数据(S_Mesh* mesh, const std::vector<T>& data) {
	mesh->f_填充顶点数据(sizeof(T), data.size(), (void*)data.data());
}
template<typename T>
void f_填充顶点数据(S_Mesh* mesh, const T* data, uint32 num) {
	mesh->f_填充顶点数据(sizeof(T), num, (void*)data);
}
template<typename T>
void f_填充索引数据(S_Mesh* mesh, const std::vector<T>& data) {
	switch (sizeof(T)) {
		case sizeof(uint32) :
			mesh->f_填充索引数据(sizeof(T), data.size(), (void*)data.data());
			break;

		case sizeof(uvec3) :
			mesh->f_填充索引数据(sizeof(uvec3), data.size(), (void*)data.data());
			break;
	}
}

Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<vec3>& data) {
	if(data.size()) mesh->f_fill顶点(data.data(), data.size());
	else mesh->f_Clear();
}
inline void f_mesh_fill顶点数据(S_Mesh* mesh, const vec3* data, uint32 num) {
	if (num) f_填充顶点数据(mesh, data, num);
	else mesh->f_Clear();
}
Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<vec4>& data) {
	if (data.size()) f_填充顶点数据<vec4>(mesh, data);
	else mesh->f_Clear();
}
Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_Sphere>& data) {
	if (data.size()) f_填充顶点数据<S_Sphere>(mesh, data);
	else mesh->f_Clear();
}
Inline void f_mesh_fill顶点数据(S_Mesh* mesh, S_线段& data) {
	mesh->f_填充顶点数据(sizeof(vec3), 2, (void*)&data);
}
Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_线段>& data) {
	if (data.size()) mesh->f_填充顶点数据(sizeof(vec3), data.size() * 2, (void*)data.data());
	else mesh->f_Clear();
}
Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_Cube>& data) {
	if (data.size()) f_填充顶点数据<S_Cube>(mesh, data);
	else mesh->f_Clear();
}
Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const std::vector<S_CurvePoint3D>& data) {
	if (data.size()) mesh->f_填充顶点数据((void*)data.data(), data.size(), E_顶点标志位::e_空间曲线);
	else mesh->f_Clear();
}
Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const S_Curve3D* data) {
	if (data->count) mesh->f_填充顶点数据(data->ptr_userData, data->count, E_顶点标志位::e_空间曲线);
	else mesh->f_Clear();
}
Inline void f_surface_fill法线数据(S_Mesh* mesh, const std::vector<vec3>& data) {
	if (data.size()) mesh->f_fill法线(data.data(), data.size());
}
inline void f_surface_fill法线数据(S_Mesh* mesh, const vec3* data, uint32 num) {
	if (num) mesh->f_fill法线(data, num);
	else mesh->f_Clear();
}
Inline void f_surface_fill纹理坐标(S_Mesh* mesh, const std::vector<vec2>& data) {
	if (data.size()) mesh->f_fillUV(data.data(), data.size(), 0);
}
Inline void f_surface_fill纹理坐标(S_Mesh* mesh, vec2* data, uint32 num, uint32 layer = 0) {
	if (num) mesh->f_fillUV(data, num, layer);
}



void f_me_fill索引(S_Mesh* me, const std::vector<uvec2>& data);
void f_me_fill索引(S_Mesh* me, const std::vector<uint32>& data);
void f_me_fill索引(S_Mesh* mesh, const std::vector<uvec3>& data);


Inline void f_mesh_fill索引数据(S_Mesh* mesh, const S_UI32Array* data) {
	if (data->count) mesh->f_填充索引数据(sizeof(uint32), data->count, data->ptr_userData);
	else mesh->f_Clear索引();
}
Inline void f_mesh_fill索引数据(S_Mesh* mesh, const uint32* data, uint32 num)  {
	if (num) mesh->f_填充索引数据(sizeof(uint32), num, (void*)data);
	else mesh->f_Clear索引();
}


Inline void f_surface_fillUV索引数据(S_Mesh* mesh, const uint32* data, uint32 num) {
	f_gbuf_fill(*mesh->m_UV索引, data, 0, num / 3);
}


void f_surface_set材质ID(S_Mesh* mesh, const std::vector<uint32>& data);

#define f_surface_fill虚线 f_mesh_fill顶点数据


Inline void f_surface_set顶点数据(S_Mesh* mesh, const std::vector<vec3>& data) {
	if (data.size() > mesh->m_顶点->m_Mem.m_数量 || data.size() < mesh->m_顶点->m_Mem.m_数量) return;
	if (data.size()) mesh->f_fill顶点(data.data(), data.size());
}

Inline void f_surface_set法线数据(S_Mesh* mesh, const std::vector<vec3>& data) {
	if (data.size() > mesh->m_顶点->m_Mem.m_数量 || data.size() < mesh->m_顶点->m_Mem.m_数量) return;
	if (data.size()) mesh->f_fill法线(data.data(), data.size());
}

Inline void f_mesh_fill顶点数据(S_Mesh* mesh, const S_Vec3Array* data) {
	if (data->count > mesh->m_顶点->m_Mem.m_数量) return;
	if (data->count) mesh->f_fill顶点(data->ptr_userData, data->count);
}

Inline void f_surface_fill法线数据(S_Mesh* mesh, const S_Vec3Array* data) {
	if (data->count > mesh->m_顶点->m_Mem.m_数量) return;
	if (data->count) mesh->f_fill法线(data->ptr_userData, data->count);
}



EngineAPI_EXPORT void f_surface_get网格顶点数据(S_Mesh* me, const S_UI32Array* index, S_Vec3Array* data, int32 成员);
EngineAPI_EXPORT void f_surface_set网格顶点数据(S_Mesh* me, const S_UI32Array* index, const S_Vec3Array* data, int32 成员);

EngineAPI_EXPORT void f_surface_push顶点(S_Mesh* mesh, const std::vector<vec3>& vert);
EngineAPI_EXPORT void f_surface_push索引(S_Mesh* mesh, const std::vector<uint32>& index);

EngineAPI_EXPORT void f_surface_fill纹理坐标索引(S_Mesh* mesh, const std::vector<uint32>& index);

Inline uint32 f_surface_fill层纹理坐标(S_Mesh* mesh, const std::vector<vec2>& data) {
	f_bm_resize(*mesh->m_UV, data.size());
	f_gbuf_fill(*mesh->m_UV, data.data(), 0, data.size());

	mesh->m_几何属性.uvLayerAndOffset.y = mesh->m_UV->m_Mem.m_偏移;
	return mesh->m_UV->m_Mem.m_偏移;
}

//Inline void f_surface_fill纹理坐标索引(S_Mesh* mesh, const std::vector<uvec3>& index) {
//	f_gbuf_resize(*mesh->m_UV索引, index.size());
//	f_gbuf_fill(*mesh->m_UV索引, index.data(), 0, index.size());
//
//	mesh->m_几何属性.uvLayerAndOffset.x = 1;
//	mesh->m_几何属性.uvLayerAndOffset.z = mesh->m_UV索引->m_Mem.m_偏移;
//}
//EngineAPI_EXPORT void f_surface_fill面(S_Mesh* me, const std::vector<S_面*>& 面);

void f_surface_fill纹理坐标索引(S_Mesh* mesh, const std::vector<uvec3> index[8]);

EngineAPI_EXPORT void f_mesh_fill面平滑模式(S_Mesh* mesh, const std::vector<bool> 平直);
EngineAPI_EXPORT void f_mesh_fill面(S_Mesh* me, const std::vector<S_FaceElement>& 面);

EngineAPI_EXPORT void f_surface_fill绘制区间(S_Mesh* me, const std::vector<S_VkDrawIndirectCommand>& indirect);
EngineAPI_EXPORT void f_surface_fill绘制区间(S_Mesh* me, const std::vector<S_VkDrawIndexedIndirectCommand>& indirect);
EngineAPI_EXPORT void f_mesh_fill绘制区间(S_Mesh* me, const S_GPU内存块& bm, uint32 firstInstance, uint32 instanceCount);


EngineAPI_EXPORT uint32 f_surface_add间接绘制(S_Mesh* mesh, const S_VkDrawIndirectCommand& indirect);
EngineAPI_EXPORT uint32 f_surface_add间接绘制(S_Mesh* mesh, const S_VkDrawIndexedIndirectCommand& indirect);
EngineAPI_EXPORT void f_surface_mov绘制区间(S_Mesh* mesh, uint32 loc);
EngineAPI_EXPORT void f_surface_set间接绘制区间(S_Mesh* mesh, const S_VkDrawIndirectCommand& indirect, uint32 loc);

Inline S_VkDrawIndirectCommand f_surface_get间接绘制区间(S_Mesh* mesh, uint32 loc) {
	return f_buf_Indirect_at(*mesh->m_间接, loc);
}

Inline void f_surface_fill邻接面索引(S_Mesh* mesh, const std::vector<uvec3>& 邻接面索引) {
	f_gbuf_fill(*mesh->m_邻接面索引, 邻接面索引.data(), 0, 邻接面索引.size());
}
Inline void f_surface_fill面法线(S_Mesh* mesh, const std::vector<vec3>& normal) {
	f_gbuf_fill(*mesh->m_面法线, normal.data(), 0, normal.size());
}
Inline void f_surface_fill面中心(S_Mesh* mesh, const std::vector<vec3>& 面中心) {
	f_gbuf_fill(*mesh->m_面中心, 面中心.data(), 0, 面中心.size());
}



Inline void f_surface_清空顶点数据(S_Mesh* mesh) {
	mesh->f_Clear();
}
Inline void f_surface_清空索引数据(S_Mesh* mesh) {
	mesh->f_Clear索引();
}





EngineAPI_EXPORT void f_mesh_fill顶点数据(S_Surface2D* mesh, const std::vector<vec2>& data);
EngineAPI_EXPORT void f_surface_fill颜色(S_Mesh* mesh, const S_RGBA8UI& color, uint32 实例S, uint32 数量);

EngineAPI_EXPORT void f_surface_get顶点数据(S_Mesh* mesh, std::vector<S_VN>& data);
EngineAPI_EXPORT void f_surface_get顶点数据(S_Mesh* mesh, std::vector<S_VC>& data);
EngineAPI_EXPORT void f_surface_get顶点坐标(S_Mesh* mesh, std::vector<vec3>& data);
EngineAPI_EXPORT void f_surface_get顶点法线(S_Mesh* mesh, std::vector<vec3>& data);
EngineAPI_EXPORT void f_surface_get纹理坐标(S_Mesh* mesh, std::vector<vec2>& data);
EngineAPI_EXPORT void f_surface_get顶点索引(S_Mesh* mesh, std::vector<uvec3>& data);
EngineAPI_EXPORT void f_surface_get顶点索引(S_Mesh* mesh, std::vector<uint32>& data);
EngineAPI_EXPORT vec3 f_surface_get顶点坐标(S_Mesh* mesh, const Mat44f& mat, uint32 id);
EngineAPI_EXPORT vec3 f_surface_get全局偏移顶点坐标(S_Mesh* mesh, const Mat44f& mat, uint32 id);

EngineAPI_EXPORT void f_surface_get材质ID(S_Mesh* mesh, std::vector<int32>& data);
EngineAPI_EXPORT void f_surface_get面平滑(S_Mesh* mesh, std::vector<int32>& data);





EngineAPI_EXPORT void f_surface_合并(const std::vector<S_Mesh*>& meshs, S_Mesh& mesh);
EngineAPI_EXPORT void f_surface_数组合并(std::vector<S_VN>& data, const DEF_3Fs& v, const DEF_3Fs& n);
EngineAPI_EXPORT void f_surface_数组合并(std::vector<S_VC>& data, const DEF_3Fs& v, const std::vector<S_RGBA8UI>& color);
EngineAPI_EXPORT void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_3Fs& n, const DEF_2Fs& t);
EngineAPI_EXPORT void f_surface_数组合并(std::vector<S_VNTC>& data, const DEF_3Fs& v, const DEF_3Fs& n, const DEF_2Fs& t);
EngineAPI_EXPORT void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_3Fs& n);
EngineAPI_EXPORT void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v, const DEF_2Fs& t);
EngineAPI_EXPORT void f_surface_数组合并(std::vector<S_VNT1>& data, const DEF_3Fs& v);
EngineAPI_EXPORT void f_surface_计算三角形球体包围盒(S_Mesh* mesh, std::vector<S_Sphere>& 包围盒);
EngineAPI_EXPORT void f_surface_计算面中心点(S_Mesh* mesh, std::vector<vec3>& 中心点);
EngineAPI_EXPORT void f_surface_计算面法线(S_Mesh* mesh, std::vector<vec3>& 法线);
EngineAPI_EXPORT void f_surface_计算面平滑法线(S_Mesh* mesh, S_点距八叉树* t);
EngineAPI_EXPORT void f_surface_变换(S_Mesh* mesh, const S_Tranform& t);
EngineAPI_EXPORT void f_surface_变换顶点(S_Mesh* mesh, const Mat44f& mat, const vec3& 缩放, const vec3& 偏移, std::vector<vec3>& 点);
EngineAPI_EXPORT S_Bounding f_mesh_计算包围盒(S_Mesh* mesh, const Mat44f* mat = nullptr);
EngineAPI_EXPORT S_Bounding f_mesh_计算包围盒(S_Mesh* mesh, uint32 vertOffset, uint32 vertNum);
EngineAPI_EXPORT S_Bounding f_surface_计算曲线包围盒(S_Mesh* mesh);
EngineAPI_EXPORT vec3 f_mesh_计算包围盒大小(S_Mesh* mesh, const Mat44f& mat);
EngineAPI_EXPORT Inline vec3 f_surface_get包围盒大小(S_Mesh* mesh, const Mat44f& mat) { return mat * f_me_get包围盒(mesh).size; }
EngineAPI_EXPORT void f_surface_计算自动权重(S_Mesh* me, const Mat44f& mat, S_骨架* 骨架, float32 封套范围比例 = 1);
EngineAPI_EXPORT void f_surface_计算封套权重(S_Mesh* me, const Mat44f& mat, S_物体* 物体, S_骨架* 骨架, float32 封套缩放 = 1);
EngineAPI_EXPORT void f_surface_构建顶点相连面索引(S_Mesh* me, std::vector<std::vector<uint32>>& 顶点相邻面);

//void f_surface_计算网格三角形法线(vec3* p顶点, uvec3* p索引, uint32* index, int32 num);

EngineAPI_EXPORT void f_surface_计算三角形边相邻面索引(S_Mesh* me);
EngineAPI_EXPORT void f_surface_计算面平滑法线(S_Mesh* mesh);
EngineAPI_EXPORT void f_surface_应用变换(S_Mesh* mesh, const Mat44f& mat);
EngineAPI_EXPORT vec3 f_surface_变换包围盒(vec3 size, const Mat44f& mat);

EngineAPI_EXPORT bool f_surface_框选线段(S_Mesh* mesh, const Mat44f& mat, const vec4 平面[5]);
EngineAPI_EXPORT bool f_surface_框选面线框(S_Mesh* mesh, const Mat44f& mat, const vec4 平面[5]);
EngineAPI_EXPORT bool f_surface_框选面(S_Mesh* mesh, const mat4& mat, const vec4 平面[5], const vec3 视锥[4][2]);
EngineAPI_EXPORT bool f_surface_框选网格边框(S_Mesh* mesh, const Mat44f mat[2], const vec4 平面[5]);

//bool f_surface_框选点包围盒(const S_Cube& cube, const vec3& position, const vec4 平面[5]);
bool f_surface_框选包围盒(const S_Cube& cube, const vec3& position, const vec4 平面[5], const vec3 视锥[4][2]);
bool f_surface_框选包围盒(const S_Cube& cube, const Mat44f 相机矩阵[2], const S_Rect2Df& view, const S_Bounding2& bound);
//bool f_surface_框选包围盒(S_Mesh* me, const Mat44f& mat, const vec4 平面[5]);

EngineAPI_EXPORT void f_surface_网格内点(S_Mesh* me, const Mat44f& mat, const S_Vec3Array* vert, S_BoolArray* 是内部, bool 反向);
bool f_surface_屏幕拾取网格(S_Mesh* mesh, const mat4& 网格变换, const Mat44f mat[2], const S_Rect2Df& view, const S_Bounding2& 框);

EngineAPI_EXPORT void f_surface_fill顶点骨骼(S_Mesh* me, std::vector<S_VertBone>& 顶点骨骼);
EngineAPI_EXPORT void f_surface_fill骨骼映射(S_Mesh* me, std::vector<S_BoneMap>& 骨骼映射);

EngineAPI_EXPORT void f_surface_设置网格平滑模式(const S_Mesh* me, S_BoolArray* 平直);

EngineAPI_EXPORT void f_surface_材质面区间(S_Mesh* me, S_材质管线* 默认材质);


S_Cube f_me_计算物体包围盒(const S_Bounding& bound, const mat3X3& mat);
S_Cube f_me_计算物体包围盒(const S_Bounding& bound, const Mat44f& mat);



struct EngineAPI_EXPORT S_Gpu相交拾取计算 {
	S_GPU计算* m_GpuCtx_坐标_法线_UV;
	S_GPU计算* m_GpuCtx_坐标_法线;
	S_GPU计算* m_GpuCtx_坐标_颜色;
	S_GPU计算* m_GpuCtx_坐标;
	S_板载缓存* m_属性参数;
	S_板载缓存* m_相交数据;
	S_板载缓存* m_参数元素[5];
	uint8		m_布局位置[5];

	S_MeshPick  m_数据偏移;

	S_Gpu相交拾取计算(S_设备环境& ctx);

	uvec3 f_updateGPU参数(S_板载缓存* 顶点, S_GPU内存块& 索引, S_Pick& info, E_顶点组合标志 顶点标志);
	//void f_run();
};


EngineAPI_EXPORT S_面拾取 f_surface_射线面相交(S_Mesh* mesh, const Mat44f mat[2], const vec3& s, const vec3& dir);
EngineAPI_EXPORT S_面拾取 f_surface_射线面相交(S_Mesh* mesh, const Mat44f mat[2], const vec3& s, const vec3& dir, const vec3& 相机位置);
EngineAPI_EXPORT S_面拾取 f_surface_射线面相交(S_Mesh* mesh, const Mat44f mat[2], const S_MeshTranformProp& 间接属性, const uvec2& Offset_num, const vec3& s, const vec3& dir);

EngineAPI_EXPORT S_线拾取 f_surface_线段相交(S_Mesh* mesh, const Mat44f mat[2], const S_MeshTranformProp& 间接属性, const uvec2& Offset_num, vec3 s, const vec3& dir, float32 最小相交距离);
EngineAPI_EXPORT S_线拾取 f_surface_线段相交(S_Mesh* mesh, const Mat44f mat[2], const vec3& s, const vec3& dir, float32& 距离, uint32 实例);
EngineAPI_EXPORT S_点拾取 f_surface_点相交(S_Mesh* mesh, const Mat44f mat[2], vec3 s, const vec3& dir, float32 最小相交距离);

EngineAPI_EXPORT float32 f_surface_射线与曲线相交(S_Mesh* mesh, const Mat44f mat[2], const vec3& s, const vec3& dir, const vec3& 相机位置, const float32& min距离);
EngineAPI_EXPORT uvec2 f_surface_射线与曲线点相交(S_Mesh* mesh, const Mat44f mat[2], const vec3& s, const vec3& dir, const vec3& 相机位置, const float32& min距离);

EngineAPI_EXPORT float32 f_surface_屏幕拾取曲线(S_Mesh* mesh, const Mat44f mat[3], const vec2& 屏幕坐标, const S_Rect2Df& rect, float32 拾取距离, vec3& 拾取坐标);
EngineAPI_EXPORT uvec2 f_surface_屏幕拾取曲线控制点(S_Mesh* mesh, const Mat44f mat[3], const vec2& 屏幕坐标, const S_Rect2Df& rect, const float32 min距离);
EngineAPI_EXPORT S_点拾取 f_surface_屏幕拾取点(S_Mesh* mesh, const Mat44f mat[3], const vec2& 屏幕坐标, const S_Rect2Df& rect, float32 min距离);

EngineAPI_EXPORT S_线拾取 f_surface_屏幕拾取线段(S_Mesh* mesh, const Mat44f mat[4], const vec2& 拾取坐标, const S_Rect2Df& rect, const uvec2& Offset_num, float32 拾取距离, uint32 元素);
EngineAPI_EXPORT S_线拾取 f_surface_屏幕拾取线段(S_Mesh* mesh, const Mat44f mat[4], const vec2& 拾取坐标, const S_Rect2Df& rect, float32 拾取距离, uint32 元素);
EngineAPI_EXPORT S_线拾取 f_surface_屏幕拾取线段(S_Mesh* mesh, const Mat44f mat[3], const vec2& 拾取坐标, const S_Rect2Df& rect, float32 拾取距离);
S_线拾取 f_surface_正面拾取屏幕线段(S_Mesh* mesh, const Mat44f mat[3], const vec2& 拾取坐标, const S_Rect2Df& rect, float32 拾取距离);




EngineAPI_EXPORT S_线拾取 f_surface_屏幕拾取三角形边(
									S_Mesh* mesh, 
									const Mat44f mat[4], 
									const vec2& 屏幕坐标, 
									const S_Rect2Df& rect, 
									float32 拾取距离, 
									uint32 元素, 
									bool 计数交点 = false);

//float32 f_surface_线段相交(S_VNT1* 顶点
//							, uvec2* 索引
//							, uint32 num
//							, const S_MeshTranformProp& 间接属性
//							, const Mat44f mat[2]
//							, vec3 s
//							, const vec3& dir
//							, float32 最小相交距离);
//

EngineAPI_EXPORT S_面拾取	f_surface_Gpu射线拾取面(S_Mesh* m, const vec3& s, const vec3& e, const Mat44f 变换矩阵[2], const vec3& 相机位置);

EngineAPI_EXPORT int32 f_surface_线相交(S_Mesh* mesh, const Mat44f& mat, const vec3& s, const vec3& e, float32& 距离);
EngineAPI_EXPORT void f_surface_排列材质槽(S_Mesh* me);

vec3 f_surface_FaceNormal(const vec3& v0, const vec3& v1, const vec3& v2);

EngineAPI_EXPORT S_Vec3Array* f_surface_点(const S_Vec3Array* 点, const S_Vec3Array* loc);



EngineAPI_EXPORT void f_mesh_fill平面(S_Mesh* me, vec2 大小, uvec2 细分);
EngineAPI_EXPORT void f_mesh_fill立方体(S_Mesh* me, vec3 大小, uvec3 细分);
EngineAPI_EXPORT void f_mesh_fill球体(S_Mesh* me, float32 大小, uvec2 细分);
EngineAPI_EXPORT void f_mesh_fill圆柱体(S_Mesh* me, vec2 大小, uvec2 细分);
EngineAPI_EXPORT void f_mesh_fillL板(S_Mesh* me, vec2 大小, float32 圆角半径, uint32 细分);




EngineAPI_EXPORT vec3 f_SampleSDFGrad(const float* sdf, uvec3& dim, ivec3& xyz);
//void f_fromMesh创建体素(S_体素& vo, S_Mesh* srcMesh, vec3 移动, vec3 旋转, vec3 缩放, float 间距, float jitter = 0.005f);

EngineAPI_EXPORT bool f_surface_构建光追底层加速结构(S_Mesh* me, E_物体类型 ObType);









EngineAPI_EXPORT void f_load网格(FILE* f, S_Mesh* obj, uint32 顶点配置标志);
EngineAPI_EXPORT void f_save网格(FILE* f, S_Mesh* obj);


EngineAPI_EXPORT void	f_mesh_save(FILE* f, const S_Mesh* me, uint32 元素位域, Mat44f* mat = nullptr, bool 压缩 = false);
EngineAPI_EXPORT void	f_mesh_load(FILE* f, S_Mesh* me, uint32 元素位域);
EngineAPI_EXPORT void	f_mesh_load(const std::vector<std::filesystem::path>& path, S_Mesh* me, uint32 元素位域);


//EngineAPI_EXPORT void f_graph_圆柱体(S_Mesh* me, vec2 大小, uvec2 细分);


EngineAPI_EXPORT void f_graph_构建平面(vec2 size, uvec2 细分, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i, DEF_Es& E, bool is三角 = true);
EngineAPI_EXPORT uvec2 f_graph_构建球体(uint32 经度细分, uint32 维度细分, float32 半径, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i, bool is三角 = true);
EngineAPI_EXPORT void f_graph_构建立方体(vec3 size, uvec3 细分, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& i, bool is三角 = true);
EngineAPI_EXPORT void f_graph_构建圆柱体(vec2 size, uvec2 细分, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& index, bool is三角 = true);
EngineAPI_EXPORT void f_graph_构建圆锥体(vec2 size, uint32 细分, DEF_3Fs& v, DEF_3Fs& n, DEF_2Fs& uv, DEF_Is& index, DEF_Es& E, bool is三角 = true);
EngineAPI_EXPORT void f_graph_构建立方体线框(vec3 size, uvec3 细分, DEF_3Fs& V, DEF_Is& I, bool is三角 = true);
EngineAPI_EXPORT void f_graph_构建骨骼锥体(vec2 size, DEF_3Fs& V, DEF_3Fs& N, DEF_Is& I, bool is三角 = true);

EngineAPI_EXPORT void f_graph_合并(std::vector<S_VNT1>& vert, std::vector<uint32>& index, const std::vector<S_VNT1>& 追加顶点, const std::vector<uint32>& 追加索引);


/**************************************************** 网格渲染 ****************************************************/

void f_me_render(S_网格包& me, S_材质管线* 线管, const E_管线槽 管线槽, float32 深度偏移);







EngineAPI_EXPORT uint32		f_vg_get图标UV(S_2D画布* s, uint32 图标, const std::string name);
EngineAPI_EXPORT S_2D图标	f_vg_2D图标(const vec2& 坐标, uint32 图标UV, const S_RGBA8UI& 颜色, float32 大小, uint32 着色类型 = DEF_DrawType_ICO_ColorInvert);

EngineAPI_EXPORT void	f_vg_tranform(S_2D画布* s, vec2 loc, vec2 scal = { 1,1 }, vec2 rot = {});
EngineAPI_EXPORT void	f_vg_setLineWidth(S_2D画布* s, uint32 元素, float32 w);
EngineAPI_EXPORT void	f_vg_tranform(S_Surface2D& surf, vec2 loc, vec2 scal = { 1,1 }, vec2 rot = {}, uint32 offset = 0);
EngineAPI_EXPORT void	f_vg_tranform(S_Surface2D& surf, uint32 num, vec2* loc);
EngineAPI_EXPORT void	f_vg_tranform(S_Surface2D& surf, uint32 num, vec2* loc, vec2* scal);
//EngineAPI_EXPORT void	f_vg_tranform(S_Surface2D& surf, vec2* loc, vec2* scal, vec2* rot, uint32 num);
EngineAPI_EXPORT void	f_vg_color(S_Surface2D& surf, uint32 num, S_RGBA8UI* color);
EngineAPI_EXPORT void	f_vg_color(S_Surface2D& surf, uint32 num, S_2D颜色包* color);


//画线
EngineAPI_EXPORT S_Surface2D*	f_vg_genLine(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式, E_线类型 线类型);
EngineAPI_EXPORT void			f_vg_setLine(S_2D画布* s, uint32 线, uint32 num, vec2* point, S_RGBA8UI* color);
EngineAPI_EXPORT void			f_vg_setLine(S_2D画布* s, uint32 线, uint32 num, vec2* point, S_RGBA8UI color);
EngineAPI_EXPORT void			f_vg_setLine(S_Surface2D& 层, uint32 num, S_GPU内存块* 块元素[], float32 线宽);
EngineAPI_EXPORT void			f_vg_setLine(S_Surface2D& 层, uint32 num, vec2* 线坐标, float32 线宽);

//画图标
EngineAPI_EXPORT uint32	f_vg_drawIco(S_2D画布* s, std::string 图标集);
EngineAPI_EXPORT void	f_vg_setIco(S_2D画布* s, uint32 图标, uint32 num, S_2D图标* ico);
EngineAPI_EXPORT void	f_vg_setIco(S_2D画布* s, uint32 图标, uint32 index, vec2 point, S_RGBA8UI color, std::string name, float32 size, uint32 绘制方式 = DEF_DrawType_ICO_ColorInvert);
//EngineAPI_EXPORT void	f_vg_ico_tranform(S_2D画布* s, uint32 元素, vec2 loc, vec2 scal = { 1,1 }, vec2 rot = {});


EngineAPI_EXPORT S_Surface2D*	f_vg_genIco(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式, E_填充模式 填充模式, std::string 图标集 = "");
EngineAPI_EXPORT void			f_vg_drawIco(S_Surface2D& surf, uint32 num, const std::u16string 图标[]);

//画UI合成
//S_Surface2D*	f_vg_genComposition(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式);
//void			f_vg_drawComposition(S_Surface2D& surf, std::vector<mat2>& 层);

//画行文本
//EngineAPI_EXPORT S_Surface2D*	f_vg_genLineText(S_设备环境& ctx, std::u16string 字体, S_2D画布& 画布, E_图层混合模式 混合模式, E_填充模式 填充模式);
//EngineAPI_EXPORT void			f_vg_lineText_begin(S_2D画布* s, uint32 行文本);
//EngineAPI_EXPORT void			f_vg_setLineText(S_2D画布* s, uint32 行文本, std::wstring text, const S_Rect2Df rect, E_对齐方式 对齐方式, S_RGBA8UI color, E_方向 方向 = E_方向::e_横向);

//画字符串
S_Surface2D*	f_vg_genPolygon(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式, E_填充模式 填充模式);
S_Surface2D*	f_vg_genString(S_设备环境& ctx, S_2D画布& 画布, E_填充模式 填充模式, E_图层混合模式 混合模式, std::u16string 字体);
void			f_vg_drawString(S_Surface2D& surf, 
								std::u16string text, 
								S_Rect2Df rect, 
								S_RGBA8UI color, 
								E_对齐方式 对齐方式,
								S_行字符串绘制属性 属性 = { 0.2, E_方向::e_横向 }
								);
void			f_vg_drawString(S_Surface2D& surf, 
								std::vector<std::u16string> text, 
								const std::vector<S_Rect2Df>& rects, 
								const std::vector<S_RGBA8UI>& color, 
								E_对齐方式 对齐方式,
								S_行字符串绘制属性
								);
void			f_vg_drawString(S_Surface2D&								surf, 
								std::vector<std::u16string>					text, 
								const std::vector<S_Rect2Df>&				rects, 
								const std::vector<S_RGBA8UI>&				color, 
								const std::vector<E_对齐方式>&				对齐方式,
								S_行字符串绘制属性
				);

void			f_vg_drawStringBlock(S_Surface2D&							surf, 
								const std::vector<std::u16string>			text, 
								const std::vector<S_Rect2Df>&				rects, 
								const std::vector<std::vector<S_RGBA8UI>>&	color, 
								const std::vector<E_对齐方式>&				对齐方式,
								S_字符串绘制属性 属性
);


float32 f_vg_getStringSize(S_Surface2D& 层, std::u16string text, float32 字号, float32 间距, E_方向 方向 = E_方向::e_横向);
float32 f_vg_getStringSize(const S_矢量字体& 字体, const std::u16string& str, float32 字号, float32 间距);
//float32 f_vg_getStringSize(const S_矢量字体& 字体, const uint16 str, float32 g);
Inline float32 f_vg_StringDrawOffset(float32 height) {
	return height * 0.2;
}

inline auto f_vg_getCharWidth = [](const S_矢量字体& 字体, const uint16 str, float32 字号) -> float32 {
	return 字体.m_字符属性[str].horiBearingX * 字号;
};

float32 f_vg_StringCutOut(const S_矢量字体& 字体, std::u16string& str, float32 width, float32 字号, float32 间距);

inline vec2 f_vg_lineStringCutOut(const S_矢量字体& 字体, std::u16string& str, S_Rect2Df rect, E_对齐方式 对齐, float32 字号, float32 间距);
inline vec2 f_vg_lineStringDrawPos(S_Rect2Df rect, float32 width, E_对齐方式 对齐) {
	vec2 pos = rect.offset;

	switch (对齐) {
		case E_对齐方式::e_据中对齐:
			pos.x += (rect.extent.x - width) * 0.5;
			break;
		case E_对齐方式::e_右对齐:
			pos.x += (rect.extent.x - width);
			break;
		default:
			pos.x += rect.extent.y * 0.2;
			break;
	}
	pos.y = rect.offset.y + f_vg_StringDrawOffset(rect.extent.y);
	return pos;
}


//void			f_vg_setLineText(S_Surface2D& surf, std::wstring text, const S_Rect2Df rect, E_对齐方式 对齐方式, S_RGBA8UI color, E_方向 方向 = E_方向::e_横向);
void f_vg_drawPolygon(S_Surface2D& 层, uint32 num, S_GPU内存块* 块元素[]);
void f_vg_drawPolygonEffect(S_Surface2D& 层, S_GPU内存块* 块元素);



//刻度
EngineAPI_EXPORT void	f_vg_setMeasure(S_2D画布* s, uint32 行文本, S_RGBA8UI color, uint32 num, const vec2* offset, const int32* 刻度, uint8 最大位数 = 10);
EngineAPI_EXPORT void	f_vg_text_tranform(S_2D画布* s, uint32 元素, vec2 loc, vec2 scal = { 1,1 }, vec2 rot = {});

//画凸包图元
S_Surface2D*	f_vg_genConvex(S_设备环境& ctx, S_2D画布& 画布, E_填充模式 填充模式, E_图层混合模式 混合模式);
 void			f_vg_drawConvex(S_Surface2D& 层, uint32 num, S_GPU内存块* 块元素[], const S_2DConvexRect* 区域, float32 线宽 = 1);

//画刻度线
EngineAPI_EXPORT S_Surface2D*	f_vg_drawTickMark(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式);
EngineAPI_EXPORT void			f_vg_setTickMark(S_Surface2D& 层, uint32 num, vec2 跨度, vec2 size, uint32 方向);

//uint32	f_vg_drawMeasure(S_2D画布* s, std::string 字体, uint32 字号);

//画波形曲线
EngineAPI_EXPORT uint32	f_vg_drawWaveform(S_2D画布* s);
EngineAPI_EXPORT void	f_vg_setWaveformRect(S_2D画布* s, uint32 元素, S_Waveform wf, float32 weidth);
EngineAPI_EXPORT void	f_vg_setWaveform(S_2D画布* s, uint32 元素, uint32 num, const float32* point);
EngineAPI_EXPORT void	f_vg_setWaveform(S_2D画布* s, uint32 元素, uint32 num, S_Waveform* wf, float32** point);

//画纹理
uint32	f_vg_drawTextures(S_2D画布* s, E_纹理类型 纹理类型, E_图层混合模式 混合模式);
void	f_vg_setTextureRect(S_2D画布* s, uint32 元素, uint32 num, const S_GPU内存块* const* 块元素, const S_2DConvexRect* rect, const uint32* texID);
void	f_vg_setTextures(S_2D画布* s, uint32 元素, uint32 num, S_纹理集** tex, uint16 绘制类型 = 0, uint16 纹理类型 = DEF_ObType_SamplerType_2DArray);
void	f_vg_setTexture(S_2D画布* s, uint32 元素, uint32 num, S_纹理* tex, uint16 绘制类型 = 0);

S_Surface2D*	f_vg_genTextures(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式);
void			f_vg_setTextures(S_Surface2D& 层, uint32 num, const S_2DConvexRect* 区域, S_GPU内存块* 形状[]);



/************************************* 辅助绘制 **************************************/
void			f_vg_begin(S_UI渲染环境& ctx, C_Widget管理* gm, vec2 offset = {});
void			f_vg_begin(C_Widget管理* gm, vec2 offset = {});
void			f_vg_render2(S_设备环境& ctx, S_2D画布& 画布, E_管线槽 管线槽);
void			f_vg_render2(S_设备环境& ctx, S_Surface2D& surf, E_管线槽 管线槽);

void			f_vg_setView(S_设备环境& ctx, vec2 xy, vec2 size);
void			f_vg_setView(S_设备环境& ctx, const S_Viewport* 视口, const S_Rect2D* 裁剪);
void			f_vg_set2DView(S_设备环境& ctx, S_Rect2Df rect, vec2* offset);
void			f_vg_setScissor(S_设备环境& ctx, const S_Rect2D* 裁剪);

S_Surface2D*	f_vg_genImage(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式);
void			f_vg_drawImage(S_设备环境& ctx, S_Surface2D& surf, S_纹理* tex, S_Rect2Df rect);

//画UI合成
S_Surface2D*	f_vg_genComposition(S_设备环境& ctx, S_2D画布& 画布, E_图层混合模式 混合模式);
void			f_vg_setComposition(S_设备环境& ctx, S_Surface2D& surf, uint32 层, uint32 层数量, S_Rect2Df rect);
void			f_vg_render(S_UI渲染环境& uiCtx, S_2D画布& 画布, E_管线槽 管线槽);

void			f_vg_CompositionBegin(S_GPU计算* ctx);
void			f_vg_Composition(S_Surface3D** face, uint32 num);
void			f_vg_end(S_设备环境& ctx, uint32 列队);

//模糊纹理
void			f_vg_Blur(C_Widget管理* gm, uvec2 分辨率, uint8 layerID);
//累积纹理
void			f_vg_Accumulate(C_Widget管理* gm, uvec2 分辨率, uint8 layerID);




/****************************** 字体 *******************************/

bool f_surface_加载矢量字体(S_设备环境& ctx, const S_字体加载参数& 字体参数, std::u16string name);
bool f_surface_卸载矢量字体(S_设备环境& ctx, std::u16string name);

void f_surface_get矢量字符网格(S_设备环境& ctx, uint16 字符, std::u16string 字体, S_Mesh* me);


/****************************** 图标 *******************************/

void f_surface_加载矢量图标(S_设备环境& ctx, std::filesystem::path 路径, std::u16string name = u"");
void f_surface_卸载矢量图标(S_设备环境& ctx, std::u16string name);

void f_surface_加载矢量图像(S_设备环境& ctx, std::filesystem::path 路径, E_三角形分割方式 分割方式);
void f_surface_卸载矢量图像(S_设备环境& ctx, std::u16string name);


S_VkDrawIndexedIndirectCommand	f_vg_getIco(const std::u16string& name, bool 面 = true);


/****************************** 复杂平面几何图形 *******************************/
std::vector<uvec2>				f_vg_genVGraph(S_2D画布* 画布, const std::u16string& name);
void							f_vg_drawVGraph(S_2D画布* 画布, const std::u16string& name, std::vector<uvec2>& 元素ID);






/***************************** 多边形 *******************************/
EngineAPI_EXPORT S_多边形*    f_surface_创建多边形();
EngineAPI_EXPORT void         f_surface_清除多边形元素(S_多边形* 多边形);
EngineAPI_EXPORT void         f_surface_销毁多边形(S_多边形* 多边形);
EngineAPI_EXPORT S_多边形元素*	f_surface_多边形桥接(S_多边形* poly, const S_边& edgeA, const S_边& edgeB);
EngineAPI_EXPORT S_Vec3Array*	f_surface_点桥接(const S_Vec3Array* a, const S_Vec3Array* b, S_UI32Array* index, S_uVec2Array* loop);
EngineAPI_EXPORT void			f_mesh_多边形三角化(S_Mesh* mesh, const S_多边形* 多边形);

EngineAPI_EXPORT std::vector<vec2>	f_mesh_get多边形网格UV(S_Mesh* mesh, const S_多边形* 多边形);

EngineAPI_EXPORT void			f_surface_合并顶点(S_多边形* 多边形, float32 最大距离 = 0.001);
EngineAPI_EXPORT void			f_surface_计算平滑法线(S_多边形* 多边形);
EngineAPI_EXPORT void			f_surface_计算三角形球体包围盒(S_多边形* 多边形, std::vector<S_Sphere>& 包围盒);
EngineAPI_EXPORT S_多边形元素*  f_surface_边网格化(S_多边形* 多边形, S_边& 边, S_边& 倒角);
EngineAPI_EXPORT float32		f_surface_边长度(S_边& 边, vec3* vert);
EngineAPI_EXPORT float32		f_surface_2D边长度(const S_Vec2Array* vert);
EngineAPI_EXPORT float32		f_surface_3D边长度(const S_Vec3Array* vert);
EngineAPI_EXPORT void			f_surface_边多点采样(S_边* 边,
	                              const vec2& 区间, 
							      float32 偏移,

							      float32 最小间隔,
							      float32 随机间隔,
							      float32 随机种子,
	                              
	                              //const vec3& 间隔_随机,
							      S_Vec3Array* 采样返回坐标,
							      S_Vec3Array* 采样返回向量
								  //, bool 变换
								  );

EngineAPI_EXPORT void	     f_surface_边采样(S_边* 边, const vec2& 区间, float32 偏移, vec3& 采样返回坐标, vec3& 采样返回向量);
EngineAPI_EXPORT void	     f_surface_以点采样边(
								const S_Vec3Array* 端点坐标, 
								const vec2& 区间, 
								float32 最小间隔,
								float32 随机间隔,
								float32 随机种子,
								bool 归一化, 
								//float32 偏移, 
								S_Vec3Array* 采样返回坐标, 
								S_Vec3Array* 采样返回向量);

EngineAPI_EXPORT void f_surface_线段方向(const S_Vec3Array* 端点坐标, S_Vec3Array* 采样返回向量);


EngineAPI_EXPORT S_多边形元素*  f_surface_复制(S_多边形* self, S_多边形元素* 面元素, const vec3& loc, const vec3& rot, const vec3& scal, uint8 合并元素);
EngineAPI_EXPORT void           f_surface_多边形元素变换(S_多边形元素* 面元素, const vec3& loc, const vec3& rot, const vec3& scal);
EngineAPI_EXPORT void           f_surface_多边形元素组变换(S_多边形元素Array* 面元素, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal);
EngineAPI_EXPORT void           f_surface_多边形变换(S_多边形* self, const vec3& loc, const vec3& rot, const vec3& scal);
EngineAPI_EXPORT S_多边形Array* f_surface_复制多边形(S_多边形* 源, const vec3& loc, const vec3& rot, const vec3& scal);
EngineAPI_EXPORT S_多边形Array* f_surface_拷贝多边形(const S_多边形Array* 源, S_多边形Array* 目标, const S_Vec3Array* loc, const S_Vec3Array* rot, const S_Vec3Array* scal);
EngineAPI_EXPORT void           f_surface_释放元素组(S_多边形* self, S_多边形元素Array* 面元素);
//void          f_surface_销毁多边形元素(S_多边形元素* 面组);

EngineAPI_EXPORT S_多边形元素Array* f_surface_线实体化(S_边Array* 边, S_Vec3Array* 倒角, S_F32Array* 半径, const S_曲线& curve, int32 节点类型, int32 半径迭代方式 = 0);


EngineAPI_EXPORT uvec2        f_surface_添加多边形顶点(S_多边形* self, S_Vec3Array* verts, S_Vec3Array* normal);
EngineAPI_EXPORT uvec2        f_surface_添加多边形法线(S_多边形* 多边形, S_Vec3Array* verts);
EngineAPI_EXPORT uvec2        f_surface_添加多边形纹理坐标(S_多边形* 多边形, const S_Vec2Array* uv, const S_UI32Array* indexs, S_uVec2Array* range);
EngineAPI_EXPORT void         f_surface_设置边形顶点法线(S_多边形* 多边形, S_Vec3Array* verts, uint32 offset);
EngineAPI_EXPORT S_边*        f_surface_添加多边形边(S_多边形* self, uvec2 offset, int32 线模式, int32 渲染模式 = 0);
EngineAPI_EXPORT S_面*			f_surface_添加多边形面(S_多边形* self, uint32* index, uint32 num, uint32 offset = 0);
EngineAPI_EXPORT S_多边形元素*	f_surface_添加多边形元素(S_多边形* self, S_Vec3Array* 顶点, S_UI32Array* 索引, S_uVec2Array* 环);
EngineAPI_EXPORT S_多边形元素*	f_surface_从区间索引构建多边形面(S_多边形* self, uvec2 index, uvec2 UV环, uint32 uv层, bool 面朝向 = true);
EngineAPI_EXPORT void			f_surface_从元素中构建多边形(S_多边形* self, S_多边形* 新多边形, uint32 元素);
EngineAPI_EXPORT void			f_poly_构建面(S_多边形* self, const S_边* 面);

EngineAPI_EXPORT void			f_surface_排列多边形材质槽(S_多边形* self);

EngineAPI_EXPORT void          f_surface_从索引构纹理面坐标(S_多边形* self, S_UI32Array* faceIndex, S_1DArray* uvIndex);
EngineAPI_EXPORT void          f_surface_取面索引(S_多边形* self, S_多边形元素* 面元素, S_1DArray* 索引);
EngineAPI_EXPORT void          f_surface_取面顶点(const S_面* 面元素, S_Vec3Array* 顶点);
EngineAPI_EXPORT void          f_surface_取面法线(const S_面* 面元素, S_Vec3Array* 法线);
EngineAPI_EXPORT void          f_surface_取面中心(const S_面* 面元素, S_Vec3Array* 中心);
EngineAPI_EXPORT void          f_surface_取面顶点法线(const S_面* 面元素, S_Vec3Array* 法线);
EngineAPI_EXPORT void          f_surface_取面元素中心(const S_多边形元素* 面元素, S_Vec3Array* 中心);
EngineAPI_EXPORT void          f_surface_取多边形面中心(const S_多边形* 多边形, S_Vec3Array* 中心);

EngineAPI_EXPORT S_边*         f_surface_取多边形边(const S_多边形* self, uint32 ID);
EngineAPI_EXPORT void          f_surface_取多边形多个元素(S_多边形* self, S_UI32Array* 元素索引, S_多边形元素Array* 元素);
EngineAPI_EXPORT S_多边形元素* f_surface_取多边形元素(S_多边形* self, uint32 元素索引);
EngineAPI_EXPORT S_面*         f_surface_取多边形面(S_多边形元素* 面元素, uint32 index);
EngineAPI_EXPORT void			f_surface_get元素索引(S_多边形* self, S_模型元素索引Array* a);

EngineAPI_EXPORT void          f_surface_设置面顶点(const S_面* 面元素, const S_Vec3Array* 顶点);
EngineAPI_EXPORT void          f_surface_设置面顶点法线(const S_面* 面元素, const S_Vec3Array* 法线);
EngineAPI_EXPORT void          f_surface_设置面法线(const S_面* 面元素, const S_Vec3Array* 法线);
EngineAPI_EXPORT void          f_surface_设置面中心(const S_面* 面元素, const S_Vec3Array* 中心);
EngineAPI_EXPORT void          f_surface_设置元素UV环(S_多边形* self, S_多边形元素* 元素, S_uVec2Array* 环, uint32 uv层);
EngineAPI_EXPORT void          f_surface_设置元素组UV环(S_多边形* self, S_多边形元素Array* 元素, S_uVec2Array* 环, uint32 uv层);
EngineAPI_EXPORT void          f_surface_设置元素材质槽ID(S_多边形* self, const S_多边形元素* 元素, S_UI32Array* 槽ID);
EngineAPI_EXPORT void          f_surface_设置元素组材质槽ID(S_多边形* self, const S_多边形元素Array* 元素, S_UI32Array* 槽ID);
EngineAPI_EXPORT void          f_surface_设置面平滑模式(S_面* 面, bool 平直);
EngineAPI_EXPORT void          f_surface_设置元素平滑模式(const S_多边形元素* 元素, S_BoolArray* 平直);
EngineAPI_EXPORT void          f_surface_设置元素组平滑模式(const S_多边形元素Array* 元素组, S_BoolArray* 平直);


EngineAPI_EXPORT void            f_surface_构建多边形边网格(S_Mesh* me, const std::vector<S_边*>& 边);
EngineAPI_EXPORT void            f_surface_构建线网格(S_Mesh* me, const std::vector<S_边*>& 边);
EngineAPI_EXPORT S_多边形元素*	f_surface_构建预设多边形(S_多边形* poly, const uvec3& 细分, const vec3& 大小, uint8 类型);
EngineAPI_EXPORT void			f_surface_投影纹理坐标(S_多边形* poly, int32 投影类型, S_多边形元素* 面元素, const Mat44f& mat);


EngineAPI_EXPORT void			f_surface_多边形转网格(const S_多边形* 多边形, S_Mesh* 面网格, S_Mesh* 点网格, S_Mesh* 边网格, bool 计算平滑法线 = true);

EngineAPI_EXPORT void			f_surface_创建自定义属性(S_多边形* 多边形, S_网格自定义属性* 类型);
EngineAPI_EXPORT void			f_surface_设置自定义属性(S_多边形* 多边形, S_网格自定义属性* 类型, S_Array* a);
EngineAPI_EXPORT void			f_surface_设置面自定义属性(S_多边形元素* 多边形元素, S_网格自定义属性* 类型, S_Array* a);
EngineAPI_EXPORT void			f_surface_设置元素自定义属性(S_多边形元素Array* 多边形元素组, S_网格自定义属性* 类型, S_Array* a);
EngineAPI_EXPORT S_GPU内存块	f_surface_填充自定义属性(S_Mesh* me, S_Array* a, int32 分布方式);



EngineAPI_EXPORT void        f_surface_多边形保存(FILE* f, const S_多边形* 多边形);
EngineAPI_EXPORT S_多边形*   f_surface_多边形加载(FILE* f);

EngineAPI_EXPORT void         f_surface_多边形保存(S_UI8Array* 块, const S_多边形* 多边形, bool 压缩);
EngineAPI_EXPORT const uint8* f_surface_多边形加载(const uint8* 块, S_多边形* 多边形, bool 压缩);

EngineAPI_EXPORT void         f_surface_网格保存(S_UI8Array* 块, const S_Mesh* me, bool 压缩);
EngineAPI_EXPORT const uint8* f_surface_网格读取(const uint8* 块, S_Mesh* me, bool 压缩);

EngineAPI_EXPORT S_多边形*	f_surface_copy(const S_多边形* 多边形);
EngineAPI_EXPORT void		f_surface_copy(const S_多边形* 多边形, S_多边形* 目标多边形);

EngineAPI_EXPORT void f_mesh_清除重复索引(S_UI32Array* 网格索引);
EngineAPI_EXPORT void f_mesh_清除网格元素中相同索引(S_UI32Array2D* 网格元素);

void f_surface_多边形生成网格(S_多边形* 多边形, S_Mesh* me, S_Mesh* edge);




// 判断点 p 是否在由 a, b, c 构成的三角形内部
bool f_polygon_isPointInTriangle(const vec3& p, const vec3& a, const vec3& b, const vec3& c);

// 耳切法进行三角剖分
std::vector<uint32_t> f_polygon_earClipping(const std::vector<vec3>& vertices, const std::vector<uint32_t>& polygon);

// 合并外边界和孔洞为一个无孔多边形
std::vector<uint32_t> f_polygon_mergeHoles(const std::vector<vec3>& vertices, const std::vector<uint32>& outer, const std::vector<std::vector<uint32>>& holes);

// 对所有环进行三角剖分
std::vector<uint32_t> f_polygon_triangulate(const std::vector<vec2>& vertices, std::vector<std::vector<uint32_t>> edgeIndices);
std::vector<uint32_t> f_polygon_从链表构建三角形(S_2D路径层 paths, float32 包围大小 = 1);


void f_polygon_剔除重复顶点索引(const std::vector<vec2>& vertices, std::vector<std::vector<uint32>>& edgeIndices);
S_2D路径层 f_polygon_构建2D路径(const std::vector<vec2>& vertices, const std::vector<std::vector<uint32>>& edgeIndices);


//用于构建扫描预构建线段
S_2D线段路径	f_polygon_构建2D线段路径(const std::vector<vec2>& vertices, const std::vector<std::vector<uint32>>& edgeIndices);
S_2D三角形		f_polygon_扫描构建三角形(const S_2D线段路径& 线段);




std::vector<uint32> f_polygon_三角化(const std::vector<S_VNTC>& 顶点, std::vector<uint32> 索引);
std::vector<uint32> f_polygon_三角化(const std::vector<S_VNTC>& 顶点, t_面顶点索引& 索引);
std::vector<uvec2> f_polygon_构建边(const std::vector<std::vector<uint32>>& 索引);

void f_polygon_构建边(S_多边形* polygon);
void f_polygon_构建多边形顶点关系(S_多边形* polygon);
void f_polygon_构建面与顶点关联(S_多边形* polygon);
void f_polygon_计算面法线(S_多边形* polygon);
void f_polygon_计算光滑法线(S_多边形* polygon);



const uint8* f_ob_Load多边形(S_多边形* polygon, const uint8* 块);
void f_ob_Save多边形(const S_多边形* polygon, S_UI8Array* 块, bool 是否压缩);








S_PolygonDataGroup f_svg_load(const std::string& path);
std::vector<PolygonData> f_svg_loads(const std::string& path);







/******************************  网格计算  *********************************/

Inline void operator+=(S_Mesh& me, const vec3 b) {
	uint32 num = (*me.m_顶点).m_Mem.m_数量;
	S_VNT1* ptr = f_bm_ptr<S_VNT1>(*me.m_顶点);
	for (uint32 i = 0; i < num; ++i) {
		ptr[i].vert += b;
	}
}

Inline void operator*=(S_Mesh& me, const vec4 b) {
	uint32 num = (*me.m_顶点).m_Mem.m_数量;
	S_VNT1* ptr = f_bm_ptr<S_VNT1>(*me.m_顶点);
	for (uint32 i = 0; i < num; ++i) {
		ptr[i].vert = f_graph_quatTranformInv(b, ptr[i].vert);
		ptr[i].normal = f_graph_quatTranformInv(b, ptr[i].normal);
	}
}

std::vector<S_VNT1> f_mesh_顶点变换(const S_Mesh& me, const Mat44f& m);
std::vector<S_VNT1> f_mesh_STL_顶点(const S_Mesh& me);
std::vector<uint32> f_mesh_STL_索引(const S_Mesh& me);

//Inline void std::vector<S_FaceElement>






EngineAPI_EXPORT uint16 f_vg_gen属性(S_2D画布* s);
EngineAPI_EXPORT uint16 f_vg_gen渐变梯度(S_2D画布* s);

EngineAPI_EXPORT S_板载缓存* f_vg_gen曲线(S_2D画布* s);
EngineAPI_EXPORT S_板载缓存* f_vg_gen曲线点索引(S_2D画布* s);
EngineAPI_EXPORT S_板载缓存* f_vg_gen颜色256(S_2D画布* s);


EngineAPI_EXPORT S_板载缓存* f_vg_gen属性(S_设备环境& m_Ctx);
Inline void f_vg_set属性(S_板载缓存* buf, const S_2D_PanelAttr& mat) {
	f_buf_set(buf, 0, mat);
}
EngineAPI_EXPORT S_GPU内存块* f_vg_gen2D变换(S_2D画布* s, uint32 num = 0);
EngineAPI_EXPORT S_GPU内存块* f_vg_gen2D颜色(S_2D画布* s, uint32 num = 0);
EngineAPI_EXPORT S_GPU内存块* f_vg_gen线属性a(S_2D画布* s);

EngineAPI_EXPORT S_GPU内存块* f_vg_gen色轮属性(S_设备环境& m_Ctx);
EngineAPI_EXPORT S_GPU内存块* f_vg_gen渐变控制(S_设备环境& m_Ctx);
EngineAPI_EXPORT S_GPU内存块* f_vg_gen渐变属性(S_设备环境& m_Ctx);


EngineAPI_EXPORT void f_vg_set属性(S_2D画布* s, uint16 eID, const S_2D_PanelAttr& mat);
EngineAPI_EXPORT void f_vg_set变换(S_2D画布* s, uint16 eID, uint32 offset, const mat3X2& mat);
EngineAPI_EXPORT void f_vg_set单色(S_2D画布* s, uint16 eID, uint32 offset, const S_RGBA8UI color);
EngineAPI_EXPORT void f_vg_setUV(S_2D画布* s, uint16 eID, uint16 icoID, uint32 offset, std::string iconame);

EngineAPI_EXPORT void f_vg_set颜色2(S_2D画布* s, uint16 eID, uint32 offset, const S_RGBA8UI colorA, const S_RGBA8UI colorB);
EngineAPI_EXPORT void f_vg_set纹理(S_2D笔刷* b, uint16 eID, S_纹理* text);
EngineAPI_EXPORT void f_vg_set纹理(S_2D画布* s, uint16 元素, uint16 eID, S_纹理* text);
EngineAPI_EXPORT void f_vg_set图元(S_2D画布* s, uint16 元素, uint32 偏移, uvec2 图元);
EngineAPI_EXPORT void f_vg_set单色(S_凸边图元& 图元, uint32 offset, const S_RGBA8UI color);


inline void f_vg_set梯度(S_2D画布* s, uint16 eID, vec2 dir, uint32 offset) {
	f_buf_set(s->m_扩展GPU参数[eID], offset, dir);
}


EngineAPI_EXPORT void f_vg_set纹理(S_2D笔刷& 笔刷, uint32 offset, S_纹理* 纹理);
EngineAPI_EXPORT S_板载缓存* f_vg_get属性(S_2D画布* s, uint16 ID);

EngineAPI_EXPORT std::wstring f_vg_set行文本(S_2D画布* s, uint32 纹理集, std::wstring text, uint32 偏移, float32 width, int32* text_ptr);
EngineAPI_EXPORT void f_vg_del文本段(S_2D画布* s, const S_2D文本对象& eID, uint32 offset, uint32 区偏移);
EngineAPI_EXPORT void f_vg_resize行文本(S_2D画布* s, const S_2D文本对象& eID, uint32 num, bool 冗余 = true);
EngineAPI_EXPORT void f_vg_set属性间隔成员(S_2D画布* s, uint16 eID, float32 v);

//EngineAPI_EXPORT uint16 f_vg_gen单色凸边形填充(S_2D画布* s, uint16 图元, uint16 变换, uint16 颜色, uint16 属性);
EngineAPI_EXPORT uint16 f_vg_gen刻度线(S_2D画布* s, uint16 属性, float32 线宽 = 1.0f);
EngineAPI_EXPORT S_凸边图元	f_vg_gen凸边图元(S_2D画布* s, const S_凸边图元& 链接元素);
EngineAPI_EXPORT S_渐变图元	f_vg_gen渐变图元(S_2D画布* s, const S_渐变图元& 链接元素);
EngineAPI_EXPORT uint16 f_vg_画行文本(S_2D画布* s, uint16 字体ID, uint16 变换, uint16 颜色, uint16 属性, uint16 字号, std::string 字体名称);
EngineAPI_EXPORT uint16 f_vg_画行文本(S_2D画布* s, S_板载缓存* 字体ID, S_板载缓存* 变换, S_板载缓存* 颜色, uint16 属性, const S_Font& 字体);

EngineAPI_EXPORT uint16 f_vg_画间接凸边形(S_2D画布* s, S_凸边图元& 图元, E_填充模式 模式, float32 线宽 = 1.0);
//EngineAPI_EXPORT uint16 f_vg_画条纹纹理(S_2D画布* s, S_凸边图元& 图元, E_填充模式 模式);
EngineAPI_EXPORT uint16 f_vg_画色轮(S_2D画布* s, S_凸边图元& 图元);
EngineAPI_EXPORT uint16 f_vg_画渐变(S_2D画布* s, S_凸边图元& 图元);

EngineAPI_EXPORT uint16 f_vg_画动态线(S_2D画布* s, uint16 属性, float32 线宽 = 1.0);
EngineAPI_EXPORT uint16 f_vg_画网格刻度线(S_2D画布* s, uint16 属性, float32 线宽 = 1.0f);
EngineAPI_EXPORT uint16 f_vg_画曲线点(S_2D画布* s, uint16 属性, S_板载缓存* 曲线点);
EngineAPI_EXPORT uint16 f_vg_画曲线(S_2D画布* s, uint16 属性, S_板载缓存* 曲线点, S_板载缓存* 曲线点ID, float32 线宽);
EngineAPI_EXPORT uint16 f_vg_画曲线(S_2D画布* s, uint16 属性, S_板载缓存* 曲线点颜色, float32 线宽, bool 多曲线 = false);
EngineAPI_EXPORT uint16 f_vg_画噪波(S_2D画布* s, uint16 属性);
EngineAPI_EXPORT uint16 f_vg_画纹理(S_2D画布* s, uint16 属性, S_纹理* 纹理);
EngineAPI_EXPORT uint16 f_vg_画多纹理(S_2D画布* s, uint16 属性, S_纹理集* 纹理, const S_MulTex_ConstPush* cp);
EngineAPI_EXPORT uint16 f_vg_画表格(S_2D画布* s, S_板载缓存* 属性);
EngineAPI_EXPORT uint16 f_vg_画矢量线(S_2D画布* s, S_板载缓存* 属性);
EngineAPI_EXPORT uint16 f_vg_画园公切线链接线(S_2D画布* s, uint16 属性, float32 线宽 = 1.0);



EngineAPI_EXPORT S_2D笔刷 f_vg_gen单色阴影(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性);
EngineAPI_EXPORT S_2D笔刷 f_vg_gen图像笔刷(S_2D画布* s, uint16 变换, uint16 属性, S_纹理* 纹理);
EngineAPI_EXPORT S_2D文本对象 f_vg_gen文本笔刷(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, uint16 字体ID, std::string 字体名称, uint16 字号);
EngineAPI_EXPORT S_2D笔刷 f_vg_gen文本块笔刷(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, const S_Font& 字体);
EngineAPI_EXPORT S_2D笔刷 f_vg_gen连接点笔(S_2D画布* s, uint16 变换, uint16 颜色, uint16 属性, uint16 配置);


EngineAPI_EXPORT uint16 f_vg_绘制矩形(S_2D画布* s, S_2D笔刷& 笔刷, const vec4& point, bool 是否填充, bool 是否开始新图元 = true);
EngineAPI_EXPORT uint16 f_vg_绘制矩形(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否填充, float32 线宽 = 1.0f, bool 是否开始新图元 = true);
//EngineAPI_EXPORT uint16 f_vg_绘制线(S_2D画布* s, std::vector<vec2>& point, float32 线宽, bool 是否开始新图元 = true);
EngineAPI_EXPORT uint16 f_vg_绘制圆角矩形(S_2D画布* s, S_2D笔刷& 笔刷, const vec4& point, float32 半径, bool 是否填充, float32 线宽 = 1.0f, bool 是否开始新图元 = true);


EngineAPI_EXPORT uint16 f_vg_画连接点(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否开始新图元 = true);
EngineAPI_EXPORT uint16 f_vg_画圆形(S_2D画布* s, S_2D笔刷& 笔刷, float32 半径, bool 是否填充, bool 是否开始新图元 = true);
EngineAPI_EXPORT uint16 f_vg_画单色图标(S_2D画布* s, uint16 属性, std::string 图标集);
EngineAPI_EXPORT uint16 f_vg_画图标(S_2D画布* s, uint16 属性, std::string 图标集);
EngineAPI_EXPORT uint16 f_vg_画文本(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否开始新图元 = true);
EngineAPI_EXPORT uint16 f_vg_画3D视口(S_2D画布* s, S_2D笔刷& 笔刷, bool 是否开始新图元 = true);
EngineAPI_EXPORT uint16 f_vg_画纹理面(S_2D画布* s, S_2D笔刷& 笔刷);


EngineAPI_EXPORT void f_vg_set绘制线(S_2D画布* s, uint16 eID, uint32 offset, const vec2& point);
EngineAPI_EXPORT void f_vg_set绘制线(S_2D画布* s, uint16 eID, uint32 num);


EngineAPI_EXPORT void f_vg_set顶点数量(S_2D画布* s, uint16 eID, int32 num);
EngineAPI_EXPORT void f_vg_set实例数量(S_2D画布* s, uint16 eID, int32 num);
Inline uint32 f_vg_set绘制数量(S_2D画布* s, uint16 eID) {
	return s->m_surf[eID].m_实例数量;
}
EngineAPI_EXPORT void f_vg_set属性(S_2D画布* s, uint16 eID, vec2 缩放, vec2 位置偏移, int32 梯度, int32 图标间隔);

//EngineAPI_EXPORT void f_vg_add变换实例(S_2D画布* s, uint16 eID, uint32 nums);
//EngineAPI_EXPORT void f_vg_add单色实例(S_2D画布* s, uint16 eID, uint32 nums);
//EngineAPI_EXPORT void f_vg_add遮罩实例(S_2D画布* s, uint16 eID, uint32 nums);




inline void f_vg_erase变换实例(S_2D画布* s, uint16 eID, uint32 num) {
	s->m_扩展GPU参数[eID]->f_map();
	f_板载缓存_remove<mat3X2>(s->m_扩展GPU参数[eID], num);
	s->m_扩展GPU参数[eID]->f_unmap();
}
inline void f_vg_erase单色实例(S_2D画布* s, uint16 eID, uint32 num) {
	s->m_扩展GPU参数[eID]->f_map();
	f_板载缓存_remove<uint32>(s->m_扩展GPU参数[eID], num);
	s->m_扩展GPU参数[eID]->f_unmap();
}

inline void f_vg_erase变换实例(S_2D画布* s, uint16 eID, uint32* e, uint32 num) {
	s->m_扩展GPU参数[eID]->f_map();
	f_板载缓存_remove<mat3X2>(s->m_扩展GPU参数[eID], e, num);
	s->m_扩展GPU参数[eID]->f_unmap();
}
inline void f_vg_erase单色实例(S_2D画布* s, uint16 eID, uint32* e, uint32 num) {
	s->m_扩展GPU参数[eID]->f_map();
	f_板载缓存_remove<uint32>(s->m_扩展GPU参数[eID], e, num);
	s->m_扩展GPU参数[eID]->f_unmap();
}
inline void f_vg_erase文本块(S_2D画布* s, uint16 eID, uint32* e, uint32 num, uint32 offset) {
	s->m_扩展GPU参数[eID]->f_map();
	f_buf_remove段_swapEnd<int32>(s->m_扩展GPU参数[eID], e, num, offset);
	s->m_扩展GPU参数[eID]->f_unmap();
}



inline bool f_vg_resize参数实例(S_2D画布* s, uint16 eID, uint32 num) {
	return f_resize板载缓存_Up(s->m_扩展GPU参数[eID], num);
}
inline void f_vg_resize间接参数(S_2D画布* s, uint16 元素, uint32 num) {
	f_bm_resize(s->m_surf[元素].m_间接, num);
}





Inline S_CurvePoint2* f_vg_map曲线坐标(S_板载缓存* b) {
	b->f_map();
	return (S_CurvePoint2*)(b->m_mappedPtr);
}

inline void	f_vg_unmapGPU参数(S_2D画布* s, uint16 eID) {
	s->m_扩展GPU参数[eID]->f_unmap();
}

Inline S_VkDrawIndirectCommand* f_vg_map间接参数(S_2D画布* s, uint16 eID) {
	//return nullptr;
	return f_buf_Indirect_ptr(s->m_surf[eID].m_间接);
	//return (S_VkDrawIndirectCommand*)(s->m_surf[eID].m_间接->m_mappedPtr);
}

template<typename T>
inline T* f_vg_map绘制数据指针(S_2D画布* s, uint16 eID) {
	s->m_扩展GPU参数[eID]->f_map();
	return (T*)s->m_扩展GPU参数[eID]->m_mappedPtr;
}
inline void f_vg_unmap绘制数据指针(S_2D画布* s, uint16 eID) {
	s->m_扩展GPU参数[eID]->f_unmap();
}

template<typename T>
void f_vg_setGPU参数(S_2D画布* s, uint16 eID, uint32 offset, const T 参数) {
	f_buf_set(s->m_扩展GPU参数[eID], offset, 参数);
}

inline uint64		f_vg_get参数数量(S_2D画布* s, uint16 eID) {
	return s->m_扩展GPU参数[eID]->m_Size;
}

inline S_板载缓存* f_vg_get参数指针(S_2D画布* s, uint16 eID) {
	return s->m_扩展GPU参数[eID];
}

inline S_板载缓存* f_vg_get属性指针(S_2D画布* s, uint16 eID) {
	return s->m_属性[eID];
}

void f_vg_关联凸边形颜色属性(const S_2D画布* s, S_2D画布* s2, uint16 层);



/******************************  纹理  *************************************/
bool f_vg_增量添加图标(S_2D画布* s, uint16 元素ID, uint16 UVID, uint32 offset, std::string iconame);

EngineAPI_EXPORT void f_vg_set图标(S_2D画布* s, uint32* icoUV, uint16 元素ID, uint16 UVID, uint32 offset, std::string iconame);

Inline float32 f_vg_get图标坐标(S_2D画布* s, uint16 元素ID, std::string iconame) {
	if (s->m_调色板->m_ICOs[s->m_surf[元素ID].m_纹理].m_Name.find(iconame) != s->m_调色板->m_ICOs[s->m_surf[元素ID].m_纹理].m_Name.end()) {
		return s->m_调色板->m_ICOs[s->m_surf[元素ID].m_纹理][iconame];
	}
	return 0;
}






//------------------------------------ !!!!!  以下废弃  !!!!!! -----------------------------------------


//Inline void f_surface_fill顶点权重(S_Mesh* mesh, const std::vector<float32>& 权重, const std::vector<uint32>& 骨骼ID) {
//	mesh->f_fill权重(权重.data(), 权重.size());
//	mesh->f_fill骨骼ID(骨骼ID.data(), 骨骼ID.size());
//}

//template<typename T>
//inline uint16 f_vg_genGPU缓存参数(S_2D画布* s, uint32 num) {
//	S_板载缓存* mat = f_buf_create板载缓存(s->m_Ctx, sizeof(T), E_板载缓存类型::e_SSBO, 1);
//	std::vector<T> data(DEF_Max(1, num));
//	f_buf_fill板载缓存(mat, data, E_板载缓存类型::e_SSBO);
//
//	if (num <= 0) mat->m_Size = 0;
//
//	s->m_扩展GPU参数.push_back(mat);
//	return uint16(s->m_扩展GPU参数.size() - 1);
//}

//template<typename T>
//inline void f_vg_add参数实例(S_2D画布* s, uint16 eID, uint32 num) {
//	std::vector<T> v(num);
//	f_buf_push_back<T>(s->m_扩展GPU参数[eID], v);
//	//f_resize板载缓存_Up(s->m_扩展GPU参数[eID], )
//}

//template<typename T>
//inline void f_vg_erase参数实例(S_2D画布* s, uint16 eID, uint32 offset) {
//	s->m_扩展GPU参数[eID]->f_map();
//	f_板载缓存_remove<T>(s->m_扩展GPU参数[eID], offset);
//	s->m_扩展GPU参数[eID]->f_unmap();
//}

//template<typename T>
//inline void f_vg_erase参数实例(S_2D画布* s, uint16 eID, uint32* e, uint32 num) {
//	s->m_扩展GPU参数[eID]->f_map();
//	f_板载缓存_remove<T>(s->m_扩展GPU参数[eID], e, num);
//	s->m_扩展GPU参数[eID]->f_unmap();
//}





